package com.meatball.authorization.service.impl

import com.meatball.authorization.data.dto.CreateRoleParams
import com.meatball.authorization.data.dto.UpdateRoleParams
import com.meatball.authorization.data.entity.RoleEntity
import com.meatball.authorization.repository.RoleRepository
import com.meatball.authorization.service.RoleService
import com.meatball.core.config.ROLE_NAME_EXISTS
import com.meatball.core.config.TARGET_AND_RESOURCE_MISMATCH
import com.meatball.core.exception.AttributeMismatchWarning
import com.meatball.core.exception.DataAlreadyExistsException
import org.springframework.stereotype.Service
import java.util.Optional

/**
 * TODO 角色管理接口实现层
 *
 * @author 张翔宇
 * @since 2024年3月26日
 */
@Service
class RoleServiceImpl(private val roleRepository: RoleRepository) : RoleService {
    override fun create(role: CreateRoleParams) {
        // 判断名称是否存在，存在则返回错误
        roleRepository.findByName(role.name) ?.also {
            throw DataAlreadyExistsException(ROLE_NAME_EXISTS)
        }
        // 不存在则新增
        roleRepository.save(RoleEntity(
            name = role.name,
            description = role.description
        ))

    }

    override fun readAll(): Iterable<RoleEntity> {
        return roleRepository.findAll()
    }

    override fun findAllRoles(): List<String> {
        return roleRepository.findAll().map {
            it.name.substring(5)
        }
    }

    override fun readById(id: Long): Optional<RoleEntity> {
        return roleRepository.findById(id)
    }

    override fun update(id: Long, role: UpdateRoleParams) {
        if (id != role.id) throw AttributeMismatchWarning(TARGET_AND_RESOURCE_MISMATCH)
        // 查询角色是否存在
        roleRepository.findByNameAndIdNot(role.name, role.id)?.also {
            throw DataAlreadyExistsException(ROLE_NAME_EXISTS)
        }
        roleRepository.findById(role.id).ifPresent {
            it.name = role.name
            it.description = role.description
            roleRepository.save(it)
        }
    }

    override fun delete(id: Long) {
        roleRepository.deleteById(id)
    }
}